package cn.xawl.gulimall.ware.service.impl;

import cn.xawl.common.constant.WareConstant;
import cn.xawl.common.utils.R;
import cn.xawl.gulimall.ware.entity.PurchaseDetailEntity;
import cn.xawl.gulimall.ware.entity.WareSkuEntity;
import cn.xawl.gulimall.ware.feign.ProductFeign;
import cn.xawl.gulimall.ware.service.PurchaseDetailService;
import cn.xawl.gulimall.ware.service.WareSkuService;
import cn.xawl.gulimall.ware.vo.PurchaseDoneVo;
import cn.xawl.gulimall.ware.vo.PurchaseDoneVoItem;
import cn.xawl.gulimall.ware.vo.PurchaseMergeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.xawl.common.utils.PageUtils;
import cn.xawl.common.utils.Query;

import cn.xawl.gulimall.ware.dao.PurchaseDao;
import cn.xawl.gulimall.ware.entity.PurchaseEntity;
import cn.xawl.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private WareSkuService wareSkuService;

    @Autowired
    private ProductFeign productFeign;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryUnReceiveList(Map<String, Object> params) {

        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>().eq("status", 0).or().eq("status", 1)
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void mergePurchaseDetail(PurchaseMergeVo purchaseMergeVo) {
        Long purchaseId = purchaseMergeVo.getPurchaseId();
        if (purchaseId == null) {
            //如果传的采购单id为空，说明要合并到新创建的采购单
            //新创建一个采购单，并设置采购单基本信息
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getStatus());
            purchaseEntity.setUpdateTime(new Date());
            purchaseEntity.setCreateTime(new Date());
            //保存新建采购单
            this.save(purchaseEntity);
            //更新需要合并的采购单id为新创建的采购单
            purchaseId = purchaseEntity.getId();
        }
        //设置一个终态的变量
        Long finalPurchaseId = purchaseId;

        //采购单不为空，使用指定的采购单
        //获取需要合并的采购需求的id
        List<Long> items = purchaseMergeVo.getItems();
        //遍历每个id，获取订单需求信息，设置每个采购订单的采购单id和状态信息
        //TODO 只有状态为新创建和已经分配的采购需求才需要合并，其他状态不需要合并。
        List<PurchaseDetailEntity> purchaseDetailList = items.stream()
                .map(item -> purchaseDetailService.getById(item))
                .filter((item) -> item.getStatus() == WareConstant.PurchaseStatusEnum.CREATED.getStatus()
                        || item.getStatus() == WareConstant.PurchaseStatusEnum.ALLOCATED.getStatus())
                .peek(item -> {
                    item.setPurchaseId(finalPurchaseId);
                    item.setStatus(WareConstant.PurchaseDetailStatusEnum.ALLOCATED.getStatus());
                })
                .collect(Collectors.toList());
        //批量更新采购需求信息
        purchaseDetailService.updateBatchById(purchaseDetailList);

        //合并完采购需求后，采购单的更新日期也需要更新
        PurchaseEntity purchase = this.getById(purchaseId);
        purchase.setUpdateTime(new Date());
        this.updateById(purchase);

    }

    @Transactional
    @Override
    public void receivePurchase(List<Long> items) {
        //首先根据需要接收的采购单id，查出采购单并且过滤掉除状态为0和1的采购单，并且将0和1状态的采购单的状态设置为已领取（2）
        List<PurchaseEntity> collect = items.stream()
                .map(this::getById)
                .filter((item) -> item.getStatus() == WareConstant.PurchaseStatusEnum.CREATED.getStatus() || item.getStatus() == WareConstant.PurchaseStatusEnum.ALLOCATED.getStatus())
                .peek(item -> item.setStatus(WareConstant.PurchaseStatusEnum.RECEIVED.getStatus()))
                .collect(Collectors.toList());

        //批量更新采购单信息
        this.updateBatchById(collect);

        //遍历采购单id查出所有的采购需求，将采购需求状态设置为正在采购(2)，更新采购需求信息
        items.forEach(id -> {
            List<PurchaseDetailEntity> purchaseDetails = purchaseDetailService.getDetailByPurchaseId(id);
            List<PurchaseDetailEntity> list = purchaseDetails.stream()
                    .peek(detail -> detail.setStatus(WareConstant.PurchaseDetailStatusEnum.PURCHASING.getStatus()))
                    .collect(Collectors.toList());
            purchaseDetailService.updateBatchById(list);
        });


    }

    @Override
    public void purchaseDone(PurchaseDoneVo purchaseDoneVo) {
        Long purchaseId = purchaseDoneVo.getId();
        List<PurchaseDoneVoItem> purchaseDoneVoItems = purchaseDoneVo.getItems();

        boolean flag = true;
        for (PurchaseDoneVoItem item : purchaseDoneVoItems) {
            Long detailId = item.getItemId();
            PurchaseDetailEntity purchaseDetail = purchaseDetailService.getById(detailId);
            //判断被采购员提交的采购项状态是否成功，如果失败，则采购项的状态和整体的采购单信息的状态应为失败（4）。
            if (item.getStatus() == WareConstant.PurchaseDetailStatusEnum.FAILURE.getStatus()) {
                flag = false;
                purchaseDetail.setStatus(item.getStatus());
            } else {
                purchaseDetail.setStatus(WareConstant.PurchaseDetailStatusEnum.FINISHED.getStatus());

                //将成功采购的货品添加（更新商品库存）
                Long skuId = purchaseDetail.getSkuId();
                WareSkuEntity ware = wareSkuService.getOne(new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId).eq("ware_id", purchaseDetail.getWareId()));
                if (ware != null) {
                    ware.setStock(ware.getStock() + purchaseDetail.getSkuNum());
                    wareSkuService.updateById(ware);
                } else {
                    //第一次采购该货品，新增一个WareSkuEntity
                    WareSkuEntity wareSkuEntity = new WareSkuEntity();
                    wareSkuEntity.setSkuId(skuId);
                    wareSkuEntity.setStock(purchaseDetail.getSkuNum());
                    wareSkuEntity.setStockLocked(0);
                    wareSkuEntity.setWareId(purchaseDetail.getWareId());

                    R info = productFeign.info(skuId);


                    if ((Integer) info.get("code") == 0) {
                        Map<String,Object> data = (Map<String, Object>) info.get("skuInfo");
                        wareSkuEntity.setSkuName((String) data.get("skuName"));
                    }


                    wareSkuService.save(wareSkuEntity);
                }

            }
            //更新采购项的状态信息
            purchaseDetailService.updateById(purchaseDetail);

        }
        //根据flag的信息，更新采购单的状态信息以及更新时间
        PurchaseEntity purchase = new PurchaseEntity();
        purchase.setId(purchaseId);
        purchase.setStatus(flag ? WareConstant.PurchaseStatusEnum.FINISHED.getStatus() : WareConstant.PurchaseStatusEnum.EXCEPTION.getStatus());
        purchase.setUpdateTime(new Date());
        this.updateById(purchase);


    }

}